import 'package:amap_location_fluttify/amap_location_fluttify.dart';
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:heytea_kit/heytea_kit.dart';
import 'package:heytea_kit/widget/refresher.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

class PoiList extends StatefulWidget {
  final ValueNotifier<Poi> poiController;
  final ValueNotifier<LatLng> centerController;
  final ValueNotifier<String> keywordController;

  const PoiList({
    @required this.poiController,
    @required this.centerController,
    this.keywordController,
  });

  @override
  _PoiListState createState() => _PoiListState();
}

class _PoiListState extends State<PoiList> {
  static const _pageSize = 30;

  final _refreshController = RefreshController();
  final _scrollController = ScrollController();
  final List<Poi> _poiList = [];

  int _loadingPage;

  @override
  void initState() {
    super.initState();

    _registerCallbacks(widget);
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (mounted) _refreshController.requestLoading(needMove: false);
    });
  }

  @override
  void didUpdateWidget(covariant PoiList oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (oldWidget.poiController != widget.poiController ||
        oldWidget.centerController != widget.centerController ||
        oldWidget.keywordController != widget.keywordController) {
      _unregisterCallbacks(oldWidget);
      _registerCallbacks(widget);

      _triggerRefresh();
    }
  }

  @override
  void dispose() {
    super.dispose();

    _unregisterCallbacks(widget);
  }

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;

    return Refresher(
      controller: _refreshController,
      onLoad: _loadAroundPoiList,
      child: ListView.builder(
        controller: _scrollController,
        itemBuilder: (context, index) {
          final poi = _poiList[index];

          return CupertinoButton(
            child: Row(
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      if (poi.title?.isNotEmpty == true)
                        Text(
                          poi.title,
                          style: textTheme.subtitle1.copyWith(
                            fontSize: 17,
                          ),
                        ),
                      const SizedBox(height: 10),
                      if (poi.address?.isNotEmpty == true)
                        Text(
                          poi.address,
                          style: textTheme.subtitle2.copyWith(
                            fontSize: 14,
                          ),
                        ),
                    ],
                  ),
                ),
                ValueListenableBuilder<Poi>(
                  valueListenable: widget.poiController,
                  builder: (context, value, child) {
                    return Visibility(
                      visible: value?.poiId == poi.poiId,
                      child: child,
                      maintainState: true,
                      maintainAnimation: true,
                      maintainSize: true,
                    );
                  },
                  child: Image.asset(
                    'assets/ic_poi_picked.png',
                    width: 20,
                    package: HeyTeaKit.packageName,
                  ),
                ),
              ],
            ),
            minSize: 0,
            padding: const EdgeInsets.all(14),
            onPressed: () => _onPoiPressed(context, poi),
          );
        },
        itemCount: _poiList.length,
      ),
      enablePullDown: false,
      enablePullUp: true,
    );
  }

  void _registerCallbacks(PoiList widget) {
    widget.centerController.addListener(_triggerRefresh);
    widget.keywordController?.addListener(_triggerRefresh);
  }

  void _unregisterCallbacks(PoiList widget) {
    widget.centerController.removeListener(_triggerRefresh);
    widget.keywordController?.removeListener(_triggerRefresh);
  }

  void _triggerRefresh() {
    // 结束当前刷新 / 加载
    if (_refreshController.isRefresh) {
      _refreshController.refreshCompleted();
    }
    if (_refreshController.isLoading) {
      _refreshController.loadComplete();
    }

    _loadAroundPoiList(Refresher.firstPage);
  }

  Future<LoadingResult> _loadAroundPoiList(int page) async {
    _loadingPage = page;

    final center = widget.centerController.value;
    final keyword = widget.keywordController?.value;

    final poiList = await AmapSearch.instance.searchAround(
      center,
      keyword: keyword ?? '',
      pageSize: _pageSize,
      page: page,
    );

    if (mounted && _loadingPage == page && center == widget.centerController.value && keyword == widget.keywordController?.value) {
      _loadingPage = null;

      if (page == Refresher.firstPage) {
        // 跳回顶部
        _scrollController.jumpTo(0.0);
      }
      setState(() {
        if (page == Refresher.firstPage) {
          // 清除旧数据
          _poiList.clear();
        }
        _poiList.addAll(poiList);
      });
    }

    if (poiList.isEmpty) {
      return LoadingResult.noData;
    } else if (poiList.length < _pageSize) {
      return LoadingResult.hasDataButNoMore;
    } else {
      return LoadingResult.hasMore;
    }
  }

  void _onPoiPressed(BuildContext context, Poi poi) {
    widget.poiController.value = poi;
    widget.centerController.value = poi.latLng;
  }
}
